package com.ys.service.sys;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.ui.Model;

import com.ys.dto.SubGridConfigDto;
import com.ys.entity.base.BaseEntity;
import com.ys.entity.shiro.LoginUser;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.service.sys.UploadService.UploadDto;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;

import lombok.AllArgsConstructor;
import lombok.Data;

public interface CommonApiService<E extends BaseEntity<E>> {

	String getCommonNextBid(Long menuId) throws Exception;

	/**
	 * 
	 * @param menuId 菜单ID，在MenuId里配置
	 * @param databaseFieldCode 数据库字段名，如Code
	 * @return 获取下一个主键编码值，格式固定为：字母+数字，如：WL0001
	 */
	String getCommonNextUkey(Long menuId, String databaseFieldCode) throws Exception;

	UploadDto uploadLocalToServer(String toFilePath) throws IOException;

	LayuiTableVoJA searchLay(E entity);

	R searchForDropdown(E entity);

    R deleteFalse(ApplicationContext ac, String className, Long id) throws Exception;

    /**
     * 通用新增页
     * @param model
     * @param entity 
     * @param menuId 菜单ID
     * @param extraParam 额外参数
     */
    String toAdd(Model model, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception;

    /**
     * 通用编辑页
     * @param model
     * @param id
     * @param entity 
     * @param menuId 菜单ID
     * @param extraParam 额外参数
     */
    String toEdit(Model model, Long id, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception;

    /**
     * 通用编辑页
     */
    ToFormDto getFormDto(String ids) throws Exception;

    /**
     * 通用详情页
     * @param model
     * @param id
     * @param entity 
     * @param menuId 菜单ID
     * @param extraParam 额外参数
     */
    String toDetail(Model model, Long id, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception;
	@Data
	@AllArgsConstructor
	public class ToFormDto{
		private ButtonDto saveBtn; // 保存按钮
		private ButtonDto deleteBtn; // 删除按钮
		private ButtonDto flowPassBtn; // 流转通过按钮
		private ButtonDto flowRefuseBtn; // 流转退回按钮
		private ButtonDto flowInitBtn; // 流转驳回按钮(退回制单)
		private ButtonDto flowLogBtn; // 流转记录按钮
		private String bid; // 单号ID
		private List<RowDto> rows;
		private FooterDto footer; // 底部
		private SubGridConfigDto subGridConfig2;
		private String urlUpload; // 上传地址
		private Map<String, Object> valueMap;

		@Data
		@AllArgsConstructor
		public static class ButtonDto {
			private Integer state; // 保存
			private String pathCommit; // 保存提交路径
		}

		@Data
		@AllArgsConstructor
		public static class FooterDto {
			private Integer show; // 是否显示，0否1是
			private String stateFlowName; // 流程状态名称
			private String createUserId; // 制单人工号
			private String createDeptId; // 制单人部门
			private String createRoleName; // 制单人岗位
		}

		@Data
		@AllArgsConstructor
		public static class RowDto {
			private String code; // 字段编码
			private String name; // 字段名称
			private String type; // 字段类型，见ENUM
			private Integer required; // 是否允许为空
			private Integer stateReadonly; // 是否只读
			private String dictKey;
			private String modalKey;
			private String modalRelativeCode;
			private String modalValueCode;
			private Integer formLength; // 表单占据长度，1代表1/3行
			private Integer formHidden; // 表单字段是否隐藏，0否1是
			private String dropdownRequestPath; // 下拉框(多选)请求路径，表单类型为下拉框(多选)时才有效
			private Integer multyFileSourceType; // 多文件控件的来源类型，关联TB_FileInfo的SourceType，表单类型为文件(多选)时才有效
			private Long multyFileSourceId; // 多文件控件的来源ID
			private String tip; // 提示文字
		}
	}
	
	/**
	 * 获取保存按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 */
	ToFormDto.ButtonDto getSaveBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	ToFormDto.ButtonDto getDeleteBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	ToFormDto.ButtonDto getFlowPassBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	ToFormDto.ButtonDto getFlowRefuseBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	ToFormDto.ButtonDto getFlowInitBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	ToFormDto.ButtonDto getFlowLogBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id);
	List<ToFormDto.RowDto> getFormRowsWhenAdd(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception;
	List<ToFormDto.RowDto> getFormRowsWhenEdit(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception;
	List<ToFormDto.RowDto> getFormRowsWhenDetail(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception;
	List<ToFormDto.RowDto> getFormRowsWhenGenerate(List<YsCol> listYsCol) throws Exception;
	ToFormDto.FooterDto getFooterForAdd(LoginUser loginUser);
	ToFormDto.FooterDto getFooterForEdit(YsProcInst ysProcInst, Long createChangeId);
	SubGridConfigDto getSubGrid(Long menuId, List<Map<String, Object>> sonlist);
	
	E dataAuth(Long menuId, E cond);

//    R deleteTrue(ApplicationContext ac, String className, Long id);
}